﻿using System;
using System.Collections.Generic;
using System.Text;
using POSPlus.MvcPassiveView;
using System.ComponentModel;
using POSPlus.EZBarTender.DatabaseOperations;
using System.Windows.Forms;
using POSPlus.DatabaseOperations;

namespace POSPlus.EZBarTender.SignsPrinting
{
	public class SignsEditorControl : MvcControlBase<SignsEditorModel, ISignsPrintingView>
	{
		public SignsEditorControl(SignsEditorModel model, ISignsPrintingView view)
		{
			view.CommitChanges += new CommitChangesEventHandler(view_CommitChanges);
			view.GetNextSign += new NextSignEventHandler(view_GetNextSign);
			view.GetPreviousSign += new PreviousSignEventHandler(view_GetPreviousSign);
			view.JobAdded += new JobAddedEventHandler(view_JobAdded);
			Initialize(model, view);
		}

		void view_GetPreviousSign(object sender, EventArgs e)
		{
			Model.CommitChanges();
			Model.PreviousSign();
		}

		void view_GetNextSign(object sender, EventArgs e)
		{
			Model.CommitChanges();
			Model.NextSign();
		}


		void view_JobAdded(object sender, EventArgs e)
		{
			Model.Editor_JobAdded();
		}

		private void view_CommitChanges(object sender, EventArgs e)
		{
			Model.CommitChanges();
		}

		protected override void WireEvents()
		{
			Model.PropertyChanged += Model_PropertyChanged;
			View.RegisterChangeRequestListener<String>("Upc", View_OnUpcChangeRequest);
			View.RegisterChangeRequestListener<String>("Description1", View_OnDescription1ChangeRequest);
			View.RegisterChangeRequestListener<String>("Description2", View_OnDescription2ChangeRequest);
			View.RegisterChangeRequestListener<String>("Description3", View_OnDescription3ChangeRequest);
			View.RegisterChangeRequestListener<String>("Description4", View_OnDescription4ChangeRequest);
			View.RegisterChangeRequestListener<String>("Description5", View_OnDescription5ChangeRequest);
			View.RegisterChangeRequestListener<double>("NormalPrice", View_OnNormalPriceChangeRequest);
			View.RegisterChangeRequestListener<double>("PriceUom", View_OnPriceUomChangeRequest);
			View.RegisterChangeRequestListener<String>("Selling", View_OnSellingChangeRequest);
			View.RegisterChangeRequestListener<String>("Size", View_OnSizeChangeRequest);
			View.RegisterChangeRequestListener<DateTime>("WeekEnding", View_OnWeekEndingChangeRequest);
			View.RegisterChangeRequestListener<double>("YouSave", View_OnYouSaveChangeRequest);
			View.RegisterChangeRequestListener<String>("SignType", View_OnSignTypeChangeRequest);
			View.RegisterChangeRequestListener<String>("SignSize", View_OnSignSizeChangeRequest);
			View.RegisterChangeRequestListener<String>("JobName", View_OnJobNameChangeRequest);
			View.RegisterChangeRequestListener<Sign>("CurrentSign", View_OnCurrentSignChangeRequest);
			View.RegisterChangeRequestListener<Int32>("DuplicateCount", View_OnDuplicateCountChangeRequest);
			View.RegisterChangeRequestListener<String>("BatchNo", View_OnBatchNoChangeRequest);
            View.RegisterChangeRequestListener<DateTime>("StartDate", View_OnStartDateChangeRequest);
		}

		protected override void UnwireEvents()
		{
			Model.PropertyChanged -= Model_PropertyChanged;
			View.UnRegisterChangeRequestListener<String>("Upc", View_OnUpcChangeRequest);
			View.UnRegisterChangeRequestListener<String>("Description1", View_OnDescription1ChangeRequest);
			View.UnRegisterChangeRequestListener<String>("Description2", View_OnDescription2ChangeRequest);
			View.UnRegisterChangeRequestListener<String>("Description3", View_OnDescription3ChangeRequest);
			View.UnRegisterChangeRequestListener<String>("Description4", View_OnDescription4ChangeRequest);
			View.UnRegisterChangeRequestListener<String>("Description5", View_OnDescription5ChangeRequest);
			View.UnRegisterChangeRequestListener<double>("NormalPrice", View_OnNormalPriceChangeRequest);
			View.UnRegisterChangeRequestListener<double>("PriceUom", View_OnPriceUomChangeRequest);
			View.UnRegisterChangeRequestListener<String>("Selling", View_OnSellingChangeRequest);
			View.UnRegisterChangeRequestListener<String>("Size", View_OnSizeChangeRequest);
			View.UnRegisterChangeRequestListener<DateTime>("WeekEnding", View_OnWeekEndingChangeRequest);
			View.UnRegisterChangeRequestListener<double>("YouSave", View_OnYouSaveChangeRequest);
			View.UnRegisterChangeRequestListener<String>("SignType", View_OnSignTypeChangeRequest);
			View.UnRegisterChangeRequestListener<String>("SignSize", View_OnSignSizeChangeRequest);
			View.UnRegisterChangeRequestListener<String>("JobName", View_OnJobNameChangeRequest);
			View.UnRegisterChangeRequestListener<Sign>("CurrentSign", View_OnCurrentSignChangeRequest);
			View.UnRegisterChangeRequestListener<Int32>("DuplicateCount", View_OnDuplicateCountChangeRequest);
			View.UnRegisterChangeRequestListener<String>("BatchNo", View_OnBatchNoChangeRequest);
            View.UnRegisterChangeRequestListener<DateTime>("StartDate", View_OnStartDateChangeRequest);
		}

		#region Change Requests
		private void View_OnUpcChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.Upc = args.RequestedValue;
		}
		private void View_OnDescription1ChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.Description1 = args.RequestedValue;
		}
		private void View_OnDescription2ChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.Description2 = args.RequestedValue;
		}
		private void View_OnDescription3ChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.Description3 = args.RequestedValue;
		}
		private void View_OnDescription4ChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.Description4 = args.RequestedValue;
		}
		private void View_OnDescription5ChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.Description5 = args.RequestedValue;
		}
		private void View_OnNormalPriceChangeRequest(Object sender, PropertyChangeRequestEventArgs<double> args)
		{
			Model.NormalPrice = args.RequestedValue;
		}
		private void View_OnPriceUomChangeRequest(Object sender, PropertyChangeRequestEventArgs<double> args)
		{
			Model.PriceUom = args.RequestedValue;
		}
		private void View_OnSellingChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.Selling = args.RequestedValue;
		}
		private void View_OnSizeChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.ProductSize = args.RequestedValue;
		}
		private void View_OnWeekEndingChangeRequest(Object sender, PropertyChangeRequestEventArgs<DateTime> args)
		{
			Model.WeekEnding = args.RequestedValue;
		}
		private void View_OnYouSaveChangeRequest(Object sender, PropertyChangeRequestEventArgs<double> args)
		{
			Model.YouSave = args.RequestedValue;
		}
		private void View_OnSignTypeChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.SignType = args.RequestedValue;
		}
		private void View_OnSignSizeChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.SignSize = args.RequestedValue;
		}
		private void View_OnJobNameChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.JobName = args.RequestedValue;
		}
		private void View_OnCurrentSignChangeRequest(Object sender, PropertyChangeRequestEventArgs<Sign> args)
		{
			Model.CurrentSign = args.RequestedValue;
		}
		private void View_OnDuplicateCountChangeRequest(Object sender, PropertyChangeRequestEventArgs<Int32> args)
		{
			Model.DuplicateCount = args.RequestedValue;
		}
		private void View_OnBatchNoChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args)
		{
			Model.BatchNo = args.RequestedValue;
		}
        private void View_OnStartDateChangeRequest(Object sender, PropertyChangeRequestEventArgs<DateTime> args)
        {
            Model.StartDate = args.RequestedValue;
        }
		#endregion

		#region Operation Request
		
		#endregion

		private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
		{
			switch (e.PropertyName)
			{
				case "Upc":
					View.Upc = Model.Upc;
					EstimateFieldValuesFromUpc(Model.Upc);
					break;
				case "Description1":
					View.Description1 = Model.Description1;
					break;
				case "Description2":
					View.Description2 = Model.Description2;
					break;
				case "Description3":
					View.Description3 = Model.Description3;
					break;
				case "Description4":
					View.Description4 = Model.Description4;
					break;
				case "Description5":
					View.Description5 = Model.Description5;
					break;
				case "JobName":
					View.JobName = Model.JobName;
					break;
				case "NormalPrice":
					View.NormalPrice = Model.NormalPrice;
					break;
				case "PriceUom":
					View.PriceUom = Model.PriceUom;
					break;
				case "Selling":
					View.Selling = Model.Selling;
					EstimateFieldValuesFromSelling(Model.Selling);
					break;
				case "Size":
					View.ProductSize = Model.ProductSize;
                    if (View.ProductSize.Split(' ').Length > 1)
                        Model.Uom = View.ProductSize.Split(' ')[1];
                    EstimateFieldValuesFromSelling(Model.Selling);
					break;
				case "WeekEnding":
					View.WeekEnding = Model.WeekEnding;
					break;
				case "YouSave":
					View.YouSave = Model.YouSave;
					break;
				case "CurrentSign":
					View.CurrentSign = Model.CurrentSign;
					View.Description1 = Model.CurrentSign.Desc1;
					View.Description2 = Model.CurrentSign.Desc2;
					View.Description3 = Model.CurrentSign.Desc3;
					View.Description4 = Model.CurrentSign.Desc4;
					View.Description5 = Model.CurrentSign.Desc5;
					View.NormalPrice = Model.CurrentSign.NormalPrice;
					View.PriceUom = Model.CurrentSign.PriceUom;
					View.ProductSize = Model.CurrentSign.Size;
					View.Selling = Model.CurrentSign.Selling;
					View.Upc = Model.CurrentSign.Upc;
					View.WeekEnding = Model.CurrentSign.WeekEnding;
					View.YouSave = Model.CurrentSign.YouSave;
					break;
				case "SignSize":
					View.SignSize = Model.SignSize;
					break;
				case "SignType":
					View.SignType = Model.SignType;
					break;
				case "DuplicateCount":
					View.DuplicateCount = Model.DuplicateCount;
					break;
				case "BatchNo":
					View.BatchNo = Model.BatchNo;
                    if(Model.BatchNo != "Smart Buy")
					    EstimateFieldValuesFromBatchNo(Model.BatchNo, Model.Upc);
					break;
                case "StartDate":
                    View.StartDate = Model.StartDate;
                    break;
				default:
					throw new ArgumentException("Property not handled: " + e.PropertyName);
			}
		}

		protected override void SetViewState()
		{
			/*
			View.CurrentSign = Model.CurrentSign;
			View.Description1 = Model.CurrentSign.Desc1;
			View.Description2 = Model.CurrentSign.Desc2;
			View.Description3 = Model.CurrentSign.Desc3;
			View.Description4 = Model.CurrentSign.Desc4;
			View.Description5 = Model.CurrentSign.Desc5;
			View.NormalPrice = Model.CurrentSign.NormalPrice;
			View.PriceUom = Model.CurrentSign.PriceUom;
			View.ProductSize = Model.CurrentSign.Size;
			View.Selling = Model.CurrentSign.Selling;
			View.Uom = Model.CurrentSign.Uom;
			View.Upc = Model.CurrentSign.Upc;
			View.WeekEnding = Model.CurrentSign.WeekEnding;
			View.YouSave = Model.CurrentSign.YouSave;
			View.SignSize = Model.SignSize;
			View.SignType = Model.SignType;
			View.DuplicateCount = Model.DuplicateCount;
			View.BatchNo = Model.BatchNo;
			 */
            Model.StartDate = View.StartDate;
			Model.JobName = View.JobName;
		}

		private void EstimateFieldValuesFromUpc(String upc)
		{
			Product product = new Product(Model.LocalConnectionString, upc);
			switch (product.PriceMethod)
			{
				case 0: Model.NormalPrice = product.NormalPrice;
					break;
				case 1: Model.NormalPrice = product.GroupPrice / product.Quantity;
					break;
			}
			Model.ProductSize = product.Size;
			ParseDescription(product.Description);
			Model.DuplicateCount = 1;
			Model.PriceUom = 0;
			Model.Selling = "";
			Model.WeekEnding = DateTime.Now;
            Model.StartDate = DateTime.Now;
			Model.YouSave = 0;
            if (!String.IsNullOrEmpty(product.Size) && product.Size.Split(' ').Length > 1)
                Model.Uom = product.Size.Split(' ')[1];
            else
                Model.Uom = product.Uom;
		}

		private void ParseDescription(String description)
		{
			String desc1 = "";
			String desc2 = "";
			String desc3 = "";
			String[] split = description.Split(' ');
			int i = 0;

			while (i < split.Length && (desc1 + split[i]).Length <= 26)
			{
				desc1 += split[i] + " ";
				i++;
			}

			while (i < split.Length && (desc2 + split[i]).Length <= 30)
			{
				desc2 += split[i];
				i++;
			}

			while (i < split.Length && (desc3 + split[i]).Length <= 30)
			{
				desc3 += split[i];
				i++;
			}

			Model.Description1 = desc1.Trim();
			Model.Description2 = desc2.Trim();
			Model.Description3 = desc3.Trim();
		}
		private void EstimateFieldValuesFromBatchNo(string batchNo, string upc)
		{
			ProductBatch batch = new ProductBatch(Model.LocalConnectionString, batchNo, upc);
			String selling = "";
			String desc4 = "";
			String desc5 = "";
			switch (batch.SpecialPriceMethod)
			{
				case 0:
					selling = batch.SpecialPrice.ToString();
					break;
				case 1: 
					selling = batch.SpecialQuantity.ToString() + "/" + batch.SpecialGroupPrice.ToString(); 
					break;
				case 2:
					selling = batch.SpecialPrice.ToString();
					desc4 = "Buy " + (batch.SpecialQuantity - 1) + " At " + ConvertMoney((double)batch.SpecialPrice);
					if (batch.SpecialGroupPrice == (batch.SpecialPrice * ((decimal)batch.SpecialQuantity - 1)))
					{
						desc5 = "Get One Free!";
					}
					else
					{
						desc5 = "Get Next For " + ConvertMoney((double)(batch.SpecialGroupPrice - 
							(batch.SpecialPrice * ((decimal)batch.SpecialQuantity - 1))));
					}
					break;
				case 3:
					selling = batch.SpecialPrice.ToString();
					desc4 = "Buy One At " + ConvertMoney((double)batch.SpecialPrice);
					desc5 = "Buy " + batch.SpecialQuantity + " For " + ConvertMoney((double)batch.SpecialGroupPrice);
					break;
				case 4:
					selling = batch.SpecialGroupPrice.ToString();
					desc4 = ConvertMoney((double)batch.SpecialGroupPrice) + " Limit " + batch.SpecialQuantity + ",";
					desc5 = "Additional For " + ConvertMoney((double)batch.SpecialPrice);
					break;
				default: break;
			}
			Model.Selling = selling;
			Model.Description4 = desc4;
			Model.Description5 = desc5;

			if (batch.BatchNo.StartsWith("AD",StringComparison.CurrentCultureIgnoreCase))
			{
				Model.SignType = "Super Sale";
			}
			else if (batch.BatchNo.StartsWith("BackRoom", StringComparison.CurrentCultureIgnoreCase) ||
				batch.BatchNo.StartsWith("BuyHoldWareHouse", StringComparison.CurrentCultureIgnoreCase) ||
				batch.BatchNo.ToLower().Contains("dsd") || batch.BatchNo.StartsWith("Seasonal") ||
				batch.BatchNo.StartsWith("Liquor", StringComparison.CurrentCultureIgnoreCase))
			{
				Model.SignType = "Special Deal";
			}
			else if (batch.BatchNo.StartsWith("Discontinued", StringComparison.CurrentCultureIgnoreCase))
			{
				Model.SignType = "Now Even Lower";
			}

			
			if (batch.DealEndDate > DateTime.Now)
			{
				Model.WeekEnding = batch.DealEndDate;
			}
			else if (batch.EndDate > (DateTime.Now + new TimeSpan(360, 0, 0, 0)))
			{
				Model.WeekEnding = DateTime.Now + new TimeSpan(180, 0, 0, 0);
			}
			else
			{
				if (batch.EndDate > new DateTime(1900, 1, 1))
					Model.WeekEnding = batch.EndDate;
				else
					Model.WeekEnding = DateTime.Now;
			}
		}
		private void EstimateFieldValuesFromSelling(String selling)
		{
            if (!String.IsNullOrEmpty(Model.ProductSize) && !String.IsNullOrEmpty(selling))
            {
                try
                {

                    int quantity;
                    double sellingPrice;

                    if (selling.Split('/').Length > 1)
                    {
                        quantity = Int32.Parse(selling.Split('/')[0]);
                        if (selling.Split('/')[1].Contains("\u00A2"))
                        {
                            sellingPrice = Double.Parse(selling.Split('/')[1].Substring(0, 2)) / 100;
                        }
                        else
                            sellingPrice = Double.Parse(selling.Split('/')[1]);
                    }
                    else if (selling.Contains("\u00A2"))
                    {
                        quantity = 1;
                        sellingPrice = Double.Parse(selling.Substring(0, 2)) / 100;
                    }
                    else
                    {
                        quantity = 1;
                        sellingPrice = Double.Parse(selling);
                    }

                    Model.YouSave = Model.NormalPrice - (sellingPrice / quantity);
                    double productSize;
                    if (Double.TryParse(Model.ProductSize.Split(' ')[0], out productSize))
                        Model.PriceUom = (sellingPrice / quantity) / productSize;
                }
                catch (FormatException)
                {
                    Model.YouSave = 0;
                }
            }
		}
		private String ConvertMoney(double money)
		{
			if (money < 1)
			{
				return Math.Round(money * 100, 0).ToString() + "\u00A2";
			}
			else
			{
				return Math.Round(money, 2).ToString("0.00");
			}
		}
	}
}
